package cn.lili.modules.member.serviceimpl;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.security.context.UserContext;
import cn.lili.common.vo.PageVO;
import cn.lili.modules.goods.client.GoodsSkuClient;
import cn.lili.modules.goods.entity.dos.GoodsSku;
import cn.lili.modules.member.entity.dos.GoodsCollection;
import cn.lili.modules.member.entity.vo.GoodsCollectionVO;
import cn.lili.modules.member.mapper.GoodsCollectionMapper;
import cn.lili.modules.member.service.GoodsCollectionService;
import cn.lili.mybatis.util.PageUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.transaction.annotation.ShardingTransactionType;
import org.apache.shardingsphere.transaction.core.TransactionType;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 会员收藏业务层实现
 *
 * @author Chopper
 * @since 2020/11/18 2:25 下午
 */
@Service
@Transactional
@ShardingTransactionType(TransactionType.BASE)
@RequiredArgsConstructor
public class GoodsCollectionServiceImpl extends ServiceImpl<GoodsCollectionMapper, GoodsCollection> implements GoodsCollectionService {

    private final GoodsSkuClient goodsSkuClient;

    @Override
    public Page<GoodsCollectionVO> goodsCollection(PageVO pageVo) {
        QueryWrapper<GoodsCollection> queryWrapper = new QueryWrapper();
        queryWrapper.eq("member_id", UserContext.getCurrentUser().getExtendId());

        queryWrapper.orderByDesc("create_time");
        Page<GoodsCollection> goodsCollections = this.page(PageUtil.initPage(pageVo), queryWrapper);

        if (goodsCollections != null && !goodsCollections.getRecords().isEmpty()) {
            List<String> skuIds = goodsCollections.getRecords().stream().map(GoodsCollection::getSkuId).collect(Collectors.toList());
            List<GoodsSku> list = goodsSkuClient.getGoodsSkuByIdFromCache(skuIds);
            Page<GoodsCollectionVO> goodsCollectionVOs = new Page<>();
            goodsCollectionVOs.setRecords(goodsCollections.getRecords().stream().map(goodsCollection -> {
                GoodsCollectionVO goodsCollectionVO = new GoodsCollectionVO();
                BeanUtils.copyProperties(goodsCollection, goodsCollectionVO);
                return goodsCollectionVO;
            }).toList());
            for (GoodsCollectionVO col : goodsCollectionVOs.getRecords()) {
                Optional<GoodsSku> matchSku = list.stream().filter(goodsSku -> goodsSku != null && goodsSku.getId().equals(col.getSkuId())).findFirst();
                if (matchSku.isEmpty()) {
                    col.setGoodsId("");
                } else {
                    BeanUtils.copyProperties(matchSku.get(), col);
                    col.setImage(matchSku.get().getThumbnail());
                }
            }
            goodsCollectionVOs.setTotal(goodsCollections.getTotal());
            goodsCollectionVOs.setCurrent(goodsCollections.getCurrent());
            goodsCollectionVOs.setSize(goodsCollections.getSize());
            return goodsCollectionVOs;
        } else {
            return new Page<>();
        }
    }

    @Override
    public boolean isCollection(String skuId) {
        QueryWrapper<GoodsCollection> queryWrapper = new QueryWrapper();
        queryWrapper.eq("member_id", UserContext.getCurrentUser().getExtendId());
        queryWrapper.eq(skuId != null, "sku_id", skuId);
        return Optional.ofNullable(this.getOne(queryWrapper)).isPresent();
    }

    @Override
    public GoodsCollection addGoodsCollection(String skuId) {
        GoodsCollection goodsCollection = this.getOne(new LambdaUpdateWrapper<GoodsCollection>()
                .eq(GoodsCollection::getMemberId, UserContext.getCurrentUser().getExtendId())
                .eq(GoodsCollection::getSkuId, skuId));
        if (goodsCollection == null) {
            goodsCollection = new GoodsCollection(UserContext.getCurrentUser().getExtendId(), skuId);

            this.save(goodsCollection);
            return goodsCollection;
        }
        throw new ServiceException(ResultCode.USER_COLLECTION_EXIST);
    }

    @Override
    public boolean deleteGoodsCollection(String skuIds) {
        QueryWrapper<GoodsCollection> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("member_id", UserContext.getCurrentUser().getExtendId());
        queryWrapper.in(CharSequenceUtil.isNotEmpty(skuIds), "sku_id", ListUtil.toList(skuIds.split(",")));
        return this.remove(queryWrapper);
    }

    @Override
    public boolean deleteGoodsCollection(List<String> goodsIds) {
        QueryWrapper<GoodsCollection> queryWrapper = new QueryWrapper();
        queryWrapper.in("sku_id", goodsIds);
        return this.remove(queryWrapper);
    }

    @Override
    public boolean deleteSkuCollection(List<String> skuIds) {
        if (skuIds == null || skuIds.isEmpty()) {
            return true;
        }
        QueryWrapper<GoodsCollection> queryWrapper = new QueryWrapper();
        queryWrapper.in("sku_id", skuIds);
        return this.remove(queryWrapper);
    }
}